﻿//load required components from google visualization API
google.load('visualization', '1', { 'packages': ['corechart', 'gauge'] });


//define object to perform ELBMonitor functions
function ELBMonitor(refreshUrl, randomise, refreshLengthMilliseconds, loadBalancerName, graphContainerId, gaugesContainerId, gaugesData, elbData) {
    //set configurable options on this instance
    this.RefreshUrl = refreshUrl;
    this.Randomise = randomise;
    this.LoadBalancerName = loadBalancerName;
    this.RefreshLengthMilliseconds = refreshLengthMilliseconds;
    this.gaugesContainerId = gaugesContainerId;

    //initialise visualizations (and keep a reference so that we can update them rather than create new ones each time.
    //browsers will crash when recreating google visualizations with a lot of data many times
    this.chart = new google.visualization.AreaChart(document.getElementById(graphContainerId));
    this.gauges = new google.visualization.Gauge(document.getElementById(gaugesContainerId));

    //get a self reference to be referred to in delegate function
    var instance = this;
    
    //perofrm display work after page-load
    google.setOnLoadCallback(function () {

        //layout grid
        instance.ResizeClientElements();

        //display cpu gauges with data passed through to initialisation
        instance.LoadCPUGagesFromJson(gaugesData);

        //layout grid
        instance.ResizeClientElements();

        //display traffic graph with data passed through to initialisation
        instance.LoadTodayYesterdayLastWeekTwoWeeksChartFromJson(elbData);

        //set interval to refresh data via ajax. remember timeout-id so wait can be cancelled.
        instance.RefreshDataTimeoutId = instance.SetTimeout();

        //on resize, re-layout
        $(window).resize(instance.ResizeClientElements);
    });

}

ELBMonitor.prototype.SetTimeout = function () {
    var self = this;
    return window.setTimeout(function () { self.RefreshAsync() }, self.RefreshLengthMilliseconds);
};

//options for cpu gauge graph
ELBMonitor.prototype.CPUGaugeOptions = {

    redFrom: 90, redTo: 100,
    yellowFrom: 75, yellowTo: 90,
    minorTicks: 5
};

//options for elb traffic day-comparison graph
ELBMonitor.prototype.ELBChartOptions = {

    curveType: "function",
    isStacked: false,
    legend: "none",
    axisTitlesPosition: 'none',
    backgroundColor: 'black',
    chartArea: { left: 50, top: 0, width: "100%", height: "75%" },
    hAxis: { textStyle: { color: 'white'} },
    vAxis: { textStyle: { color: 'white'} },
    colors: ['green', 'yellow', 'red', 'blue']
};

ELBMonitor.prototype.RefreshAsync = function () {
    //since this function could be called manually, clear any timeout waiting to call this method, since we don't want 
    //to be interrupted and we will reset the timeout anyway when the data is retreived and set.
    window.clearTimeout(this.RefreshDataTimeoutId);

    //self-reference for callbacks
    var instance = this;
    var data = null;
    if (this.Randomise === false)
        var data = ({ loadBalancerName: this.LoadBalancerName });

    $.ajax({
        url: this.RefreshUrl,
        type: 'POST',
        data: data,
        dataType: 'json',
        error: function (error) {
            alert(error);
        },
        success: function (result) {
            //if set to random, then we could receive a different site, therefore change the source of the iframe to the current
            //loadbalancer's Url
            if (instance.Randomise === true)
                $("#Site").attr("src", result.LoadBalancerUrl);

            //set cpu charts
            //do this first since the area could be resized as part of this
            instance.LoadCPUGagesFromJson(result.CPU);

            //client element sizes may have been altered as a result of visualization drawing, so recalculate positions
            instance.ResizeClientElements();

            //set ELB request data
            instance.LoadTodayYesterdayLastWeekTwoWeeksChartFromJson(result.Data);

            //set interval to refresh data via ajax. remember timeout-id so wait can be cancelled.
            instance.RefreshDataTimeoutId = instance.SetTimeout();

        }
    });
};


//function to display CPU gague data
ELBMonitor.prototype.LoadCPUGagesFromJson = function (dataItems) {
    //initialise data table
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Label');
    data.addColumn('number', 'Value')

    //add rows for each data item we have
    data.addRows(dataItems.length);

    //parse data, setting value for each cell as we find them
    for (var j in dataItems) {
        data.setValue(parseInt(j), 0, dataItems[j].Instance);
        data.setValue(parseInt(j), 1, dataItems[j].Data[0]);
    }

    //set new width of container to allow for varying length of data rows, consider 100x100 minimum for each gauge
    $("#" + this.gaugesContainerId).css("width", function(){
            return ((Math.ceil(dataItems.length / 
                    (Math.floor($(this).height() / 100)) //items high
                ) * 100) 
            + "px")
          });
    //draw new data to chart
    this.gauges.draw(data, this.CPUGaugeOptions);
};


//function to display ELB traffic day-comparison data
ELBMonitor.prototype.LoadTodayYesterdayLastWeekTwoWeeksChartFromJson = function (dataItems) {
    //initialise data table
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Date');
    data.addColumn('number', '2wks');
    data.addColumn('number', '1wk');
    data.addColumn('number', 'ydy');
    data.addColumn('number', 'tdy');

    //add rows for each data item we have
    data.addRows(dataItems.length);

    //parse data, setting value for each cell as we find them
    for (var j in dataItems) {
        data.setValue(parseInt(j), 0, dataItems[j].Date);
        for (var k in dataItems[j].Data) {
            data.setValue(parseInt(j), parseInt(k) + 1, dataItems[j].Data[k] == 0 ? null : dataItems[j].Data[k]);
        }
    }

    //draw new data to chart
    this.chart.draw(data, this.ELBChartOptions);
};


ELBMonitor.prototype.ResizeClientElements = function () {
    
    //adjust content height to window height, maintaining height of graph-view
    $('#Site').css('height', $(window).height() - $('#AllELBRequests').height());
    
    //adjust content width to window width, maintaining width of gauge-view
    $('#AllELBRequests, #Site').css("width", $("#Gauges").position().left);
    
};